package com.library.librarybackend.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.digest.BCrypt;
import com.library.librarybackend.domain.constant.GlobalConstant;
import com.library.librarybackend.domain.dto.BatchRegisterFormDTO;
import com.library.librarybackend.domain.dto.LoginFormDTO;
import com.library.librarybackend.domain.dto.RegisterFormDTO;
import com.library.librarybackend.domain.entity.User;
import com.library.librarybackend.domain.enums.GenderEnum;
import com.library.librarybackend.domain.enums.RoleEnum;
import com.library.librarybackend.domain.vo.UserVO;
import com.library.librarybackend.handler.exception.BusinessException;
import com.library.librarybackend.service.AuthService;
import com.library.librarybackend.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author 平
 * @description 认证服务
 * @since 2025-09-20 20:53
 */
@Service
@RequiredArgsConstructor
public class AuthServiceImpl implements AuthService {

    private final UserService userService;


    @Override
    public UserVO login(LoginFormDTO loginFormDTO) {
        String account = loginFormDTO.getAccount();
        String password = loginFormDTO.getPassword();
        // 查询是否存在
        User user = userService.lambdaQuery()
                .eq(User::getAccount, account)
                .oneOpt()
                .orElseThrow(() -> new BusinessException("用户不存在"));
        // 密码校验
        if (!BCrypt.checkpw(password, user.getPassword())) {
            throw new BusinessException("密码错误");
        }
        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
        // 开启会话认证
        baseLogin(userVO);
        return userVO;
    }

    @Override
    public void logout() {
        // 清除会话信息
        StpUtil.getSession().clear();
        // 登出
        StpUtil.logout();
    }

    @Override
    public void register(RegisterFormDTO registerFormDTO) {
        // 判断是否有这个角色
        if (!RoleEnum.isExist(registerFormDTO.getRole())) {
            throw new BusinessException("角色不存在");
        }
        // 判断性别是否有
        if (null != registerFormDTO.getGender() && !GenderEnum.isExist(registerFormDTO.getGender())) {
            throw new BusinessException("性别不存在");
        }
        // 查询是否存在
        userService.lambdaQuery()
                .eq(User::getAccount, registerFormDTO.getAccount())
                .oneOpt()
                .ifPresent(user -> {
                    throw new BusinessException("用户已存在");
                });
        User user = BeanUtil.copyProperties(registerFormDTO, User.class);
        user.setPassword(BCrypt.hashpw(user.getPassword()));
        userService.save(user);
    }

    @Override
    public void batchRegister(BatchRegisterFormDTO batchRegisterFormDTO) {
        UserVO currentUser = StpUtil.getSession().getModel(GlobalConstant.USER_SESSION, UserVO.class);
        List<User> userList = batchRegisterFormDTO.getRegisterFormList()
                .stream()
                .map(registerFormDTO -> {
                    // 判断是否有这个角色
                    if (!RoleEnum.isExist(registerFormDTO.getRole())) {
                        throw new BusinessException("角色不存在");
                    }
                    // 判断当前账户权限是否大于等于注册的账户权限
                    if (currentUser.getRole() >= registerFormDTO.getRole()) {
                        throw new BusinessException("权限不足");
                    }
                    // 判断性别是否有
                    if (null != registerFormDTO.getGender() && !GenderEnum.isExist(registerFormDTO.getGender())) {
                        throw new BusinessException("性别不存在");
                    }
                    return BeanUtil.copyProperties(registerFormDTO, User.class);
                })
                .distinct()
                .toList();
        // 判断是否存在账号
        if (userService.lambdaQuery()
                .in(User::getAccount, userList.stream().map(User::getAccount))
                .exists()) {
            throw new BusinessException("账号已存在");
        }
        // 批量保存用户
        userService.saveBatch(userList);
    }


    private void baseLogin(UserVO user) {
        // 登录
        StpUtil.login(user.getId());
        // 填充会话信息
        StpUtil.getSession().set(GlobalConstant.USER_SESSION, user);
    }

}
